package com.zjsru.plan2025.oneday;

/**
 * 2241. 设计一个 ATM 机器
 * @Author: cookLee
 * @Date: 2025-01-05
 */
public class ATM {

    /**
     * 自动取款机
     * 比方说，你想取 $300 ，并且机器里有 2 张 $50 的钞票，1 张 $100 的钞票和1 张 $200 的钞票，那么机器会取出 $100 和 $200 的钞票。
     * 但是，如果你想取 $600 ，机器里有 3 张 $200 的钞票和1 张 $500 的钞票，那么取款请求会被拒绝，因为机器会先取出 $500 的钞票，然后无法取出剩余的 $100 。注意，因为有 $500 钞票的存在，机器 不能 取 $200 的钞票。
     * \
     * 输入：
     * ["ATM", "deposit", "withdraw", "deposit", "withdraw", "withdraw"]
     * [[], [[0,0,1,2,1]], [600], [[0,1,0,1,1]], [600], [550]]
     * 输出：
     * [null, null, [0,0,1,0,1], null, [-1], [0,1,0,0,1]]
     * \
     * 解释：
     * ATM atm = new ATM();
     * atm.deposit([0,0,1,2,1]); // 存入 1 张 $100 ，2 张 $200 和 1 张 $500 的钞票。
     * atm.withdraw(600);        // 返回 [0,0,1,0,1] 。机器返回 1 张 $100 和 1 张 $500 的钞票。机器里剩余钞票的数量为 [0,0,0,2,0] 。
     * atm.deposit([0,1,0,1,1]); // 存入 1 张 $50 ，1 张 $200 和 1 张 $500 的钞票。
     *                           // 机器中剩余钞票数量为 [0,1,0,3,1] 。
     * atm.withdraw(600);        // 返回 [-1] 。机器会尝试取出 $500 的钞票，然后无法得到剩余的 $100 ，所以取款请求会被拒绝。
     *                           // 由于请求被拒绝，机器中钞票的数量不会发生改变。
     * atm.withdraw(550);        // 返回 [0,1,0,0,1] ，机器会返回 1 张 $50 的钞票和 1 张 $500 的钞票。
     */

    private final long[] count;
    private final long[] cush;

    public ATM() {
        //从小到大钱的数量
        this.count = new long[]{0, 0, 0, 0, 0};
        //面额
        this.cush = new long[]{20, 50, 100, 200, 500};
    }

    /**
     * 存款.存入的数量
     *
     * @param banknotesCount 纸币计数
     */
    public void deposit(int[] banknotesCount) {
        int len = banknotesCount.length;
        for (int i = 0; i < len; i++) {
            this.count[i] += banknotesCount[i];
        }
    }

    public int[] withdraw(int amount) {
        int[] res = new int[5];
        //从大到小开始取钱
        for (int i = 4; i >= 0; i--) {
            res[i] = (int) Math.min(amount / this.cush[i], this.count[i]);
            //减去取出的钱
            amount -= (int) (res[i] * this.cush[i]);
        }
        if (amount > 0) {
            return new int[]{-1};
        } else {
            //减去取出的钱
            for (int i = 0; i < 5; i++) {
                this.count[i] -= res[i];
            }
            return res;
        }
    }

}
